#include <iostream>

using namespace std;

// PCB结构体定义
struct PCB
{
    string process_name; // 进程名
    int priority;        // 优先级
    int required_time;   // 要求运行时间
    int remaining_time;  // 剩余运行时间
    int wait_time;       // 剩余等待时间
    string wait_reason;
    string status;       // 状态
    PCB *next = nullptr; // 下一个PCB指针
    void print()
    {
        cout << process_name << " 优先级 : " << priority << " 剩余时间 : " << remaining_time << endl;
    }
};
// 初始化进程控制块
void init_pcb(PCB *pcb, string name)
{
    pcb->process_name = name;
    cout << "请输入" << name << "的要求运行时间：";
    cin >> pcb->required_time;
    cout << "请输入" << name << "的优先级：";
    cin >> pcb->priority;
    pcb->remaining_time = pcb->required_time;
    pcb->status = "就绪";
    pcb->next = nullptr;
}

// 创建进程控制块
PCB *create_pcb(string name)
{
    PCB *pcb = new PCB;
    init_pcb(pcb, name);
    return pcb;
}
class PCBList
{
public:
    PCBList(string name) : list_name(name)
    {
        // 创建虚拟头节点
        head = new PCB;
    }

    // 插入新元素
    virtual void insert(PCB *new_pcb)
    {
        new_pcb->status = list_name;
        PCB *prev = head;
        while (prev->next != nullptr && prev->next->priority >= new_pcb->priority)
        {
            prev = prev->next;
        }
        new_pcb->next = prev->next;
        prev->next = new_pcb;
    }
    virtual void update_list(){};

    // 删除指定位置的元素
    void remove(int index)
    {
        PCB *prev = head;
        for (int i = 0; i < index && prev->next; i++)
        {
            prev = prev->next;
        }
        if (prev->next)
        {
            PCB *temp = prev->next;
            prev->next = temp->next;
            temp->next = nullptr;
        }
    }

    // 获取指定位置的元素
    PCB *get(int index)
    {
        PCB *current = head->next;
        for (int i = 0; i < index && current; i++)
        {
            current = current->next;
        }
        return current;
    }

    // 打印链表信息
    virtual void print()
    {
        cout << list_name << "队列" << endl;
        cout << "---------------------" << endl;
        cout << "Name\tPriority\tReq. Time\tRem. Time\tStatus" << endl;
        PCB *current = head->next;
        while (current)
        {
            cout << current->process_name << "\t";
            cout << current->priority << "\t\t";
            cout << current->required_time << "\t\t";
            cout << current->remaining_time << "\t\t";
            cout << current->status << endl;
            current = current->next;
        }
    }

    bool empty()
    {
        return head->next == nullptr;
    }

protected:
    PCB *head; // 虚拟头节点
    string list_name;
};

class BlockList : public PCBList
{
protected:
    PCBList *block_ready;

public:
    BlockList(string name, PCBList *block_ready)
        : PCBList(name), block_ready(block_ready)
    {
    }
    // 根据剩余等待时间插入
    void insert(PCB *new_pcb) override
    {
        new_pcb->status = list_name;
        PCB *prev = head;
        while (prev->next != nullptr && prev->next->wait_time <= new_pcb->wait_time)
        {
            prev = prev->next;
        }
        new_pcb->next = prev->next;
        prev->next = new_pcb;
    }
    // 每过一个时间片将所有进程等待时间减一
    void update_list() override
    {
        auto pre = head;
        while (pre->next)
        {
            pre->next->wait_time--;
            pre = pre->next;
        }
        // 取出等待时间到了的
        while (head->next && head->next->wait_time == 0)
        {
            auto tmp = head->next;
            remove(0); // 去掉第零个元素
            block_ready->insert(tmp);
        }
    }
    void print() override
    {
        cout << list_name << "队列" << endl;
        cout << "---------------------" << endl;
        cout << "Name\tPriority\tReq. Time\tRem. Time\tStatus\tWait_Time\tWait_Reason" << endl;
        PCB *current = head->next;
        while (current)
        {
            cout << current->process_name << "\t";
            cout << current->priority << "\t\t";
            cout << current->required_time << "\t\t";
            cout << current->remaining_time << "\t\t";
            cout << current->status << "\t\t";
            cout << current->wait_time << "\t\t";
            cout << current->wait_reason << "\t\t" << endl;
            current = current->next;
        }
    }
};
